unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, uPSUtils;

type
  TForm1 = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TCodeTokenItem = record
    TokenID: TPSPasToken;
    Col: integer;
    TokenText: string;
  end;
  PCodeTokenItem = ^TCodeTokenItem;

  TCodeTokenList = class
  private
    FList: TList;
    procedure Clear;
    function GetCount: integer;
    function GetItem(i: integer): PCodeTokenItem;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Process(const CodeLine: string);
    function FindTokenByCol(Col: integer): integer;
    property Count: integer read GetCount;
    property Tokens[index: integer]: PCodeTokenItem read GetItem;
  end;

var
  Form1             : TForm1;

implementation

{$R *.dfm}

function AnyzStringIdent(const line: widestring; var NotCloseStrBeginIdx: integer): boolean;
var
  i, StringState    : integer;
  C                 : WideChar;
begin
  Result := false;
  StringState := -1;
  NotCloseStrBeginIdx := -1;
  for i := 1 to length(line) do
  begin
    C := line[i];
    case C of
      '''':
        begin
          case StringState of
            -1:
              begin
                StringState := 1;
                NotCloseStrBeginIdx := i;
              end;
            1: StringState := 0;
            0: StringState := 1;
            3: Exit;
          end;
        end;
      ' ', Chr(VK_TAB):
        begin
          if StringState = 0 then
            StringState := 3;
        end;
    else
      begin
        if StringState in [0, 3] then
          StringState := -1;
      end;
    end;
  end;
  Result := true;
  if StringState <> 1 then
    NotCloseStrBeginIdx := -1;
end;

{ TCodeTokenList }

procedure TCodeTokenList.Clear;
var
  i                 : integer;
begin
  for i := 0 to FList.Count - 1 do
    dispose(PCodeTokenItem(FList[i]));
  FList.Clear;
end;

constructor TCodeTokenList.Create;
begin
  FList := TList.Create;
end;

destructor TCodeTokenList.Destroy;
begin
  Clear;
  FList.Free;
  inherited;
end;

function TCodeTokenList.FindTokenByCol(Col: integer): integer;
var
  i                 : integer;
begin
  result := -1;
  for i := 0 to count - 1 do
  begin
    if i <= count - 2 then
    begin
      if (col >= tokens[i].Col) and (col < tokens[i + 1].Col) then
      begin
        result := i;
        Exit;
      end;
    end
    else
    begin
       if Col>=tokens[i].Col then
       begin
         result:=i;
         Exit;
       end;
    end;
  end;
end;

function TCodeTokenList.GetCount: integer;
begin
  Result := FList.Count;
end;

function TCodeTokenList.GetItem(i: integer): PCodeTokenItem;
begin
  Result := PCodeTokenItem(FList[i]);
end;

procedure TCodeTokenList.Process(const CodeLine: string);
var
  parser            : TPSPascalParser;
  item              : PCodeTokenItem;
begin
  clear;
  parser := TPSPascalParser.Create;
  try
    parser.SetText(CodeLine);
    while parser.CurrTokenID <> CSTI_EOF do
    begin
      new(item);
      item.TokenID := parser.CurrTokenID;
      item.Col := parser.Col;
      item.TokenText := parser.OriginalToken;
      FList.Add(item);
      parser.Next;
    end;
  finally
    parser.Free;
  end;
end;

end.

 